import axios, {
  AxiosInstance,
  InternalAxiosRequestConfig,
  AxiosResponse,
} from "axios";
import { message } from "antd";

// 定义响应数据结构（兼容后端返回格式）
export interface ApiResponse<T = any> {
  code: number;
  msg?: string; // 后端返回字段
  message?: string; // 前端期望字段
  data: T;
  timestamp?: number;
}

// 创建axios实例
const request: AxiosInstance = axios.create({
  baseURL: process.env.REACT_APP_API_BASE_URL || "http://localhost:8080",
  timeout: 30000,
  headers: {
    "Content-Type": "application/json",
  },
});

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 从localStorage获取token
    const token = localStorage.getItem("authToken") || localStorage.getItem("token");
    if (token) {
      // 后端返回的token已经包含xht-teach-admin前缀，直接使用
      config.headers.Authorization = `Bearer ${token}`;
    }

    // 添加时间戳防止缓存
    if (config.method === "get") {
      config.params = {
        ...config.params,
        _t: Date.now(),
      };
    }

    return config;
  },
  (error) => {
    console.error("请求错误:", error);
    return Promise.reject(error);
  }
);

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const { data } = response;

    // 检查业务状态码 (兼容code为0或者code不存在的情况)
    if (data.code === 0 || data.code === undefined) {
      return response;
    } else if (data.code === 401) {
      // token过期或无效
      const errorMsg = data.msg || data.message || "登录已过期，请重新登录";
      message.error(errorMsg);
      // 清理所有可能的token存储
      localStorage.removeItem("token");
      localStorage.removeItem("authToken");
      localStorage.removeItem("currentUser");
      localStorage.removeItem("authUser");
      sessionStorage.removeItem("authToken");
      sessionStorage.removeItem("authUser");
      // 跳转到登录页
      window.location.href = "/login";
      return Promise.reject(new Error("未授权"));
    } else if (data.code === -1) {
      // 系统繁忙或业务错误
      const errorMsg = data.msg || data.message || "系统繁忙，请稍后重试";
      message.error(errorMsg);
      return Promise.reject(new Error(errorMsg));
    } else {
      // 其他业务错误
      const errorMsg = data.msg || data.message || "请求失败";
      message.error(errorMsg);
      return Promise.reject(new Error(errorMsg));
    }
  },
  (error) => {
    console.error("响应错误:", error);

    if (error.response) {
      const { status, data } = error.response;

      switch (status) {
        case 401:
          message.error("登录已过期，请重新登录");
          // 清理所有可能的token存储
          localStorage.removeItem("token");
          localStorage.removeItem("authToken");
          localStorage.removeItem("currentUser");
          localStorage.removeItem("authUser");
          sessionStorage.removeItem("authToken");
          sessionStorage.removeItem("authUser");
          window.location.href = "/login";
          break;
        case 403:
          message.error("没有权限访问");
          break;
        case 404:
          message.error("请求的资源不存在");
          break;
        case 500:
          message.error("服务器内部错误");
          break;
        default:
          const errorMsg = data?.msg || data?.message || `请求失败 (${status})`;
          message.error(errorMsg);
      }
    } else if (error.request) {
      // 网络错误
      message.error("网络连接错误，请检查网络设置");
    } else {
      message.error("请求配置错误");
    }

    return Promise.reject(error);
  }
);

// 创建便捷的请求方法，自动提取data
const api = {
  get: <T = any>(
    url: string,
    config?: InternalAxiosRequestConfig
  ): Promise<ApiResponse<T>> =>
    request.get(url, config).then((res) => res.data),

  post: <T = any>(
    url: string,
    data?: any,
    config?: InternalAxiosRequestConfig
  ): Promise<ApiResponse<T>> =>
    request.post(url, data, config).then((res) => res.data),

  put: <T = any>(
    url: string,
    data?: any,
    config?: InternalAxiosRequestConfig
  ): Promise<ApiResponse<T>> =>
    request.put(url, data, config).then((res) => res.data),

  delete: <T = any>(
    url: string,
    config?: InternalAxiosRequestConfig
  ): Promise<ApiResponse<T>> =>
    request.delete(url, config).then((res) => res.data),
};

export default api;
